package com.auxide.cah;

import java.util.Arrays;

import org.json.JSONArray;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.InputFilter;
import android.text.InputType;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;

import com.auxide.util.Logger;
import com.auxide.util.NetworkManager;
import com.auxide.util.Preferences;

public class HostGame extends Activity implements OnClickListener{

	TextView ipTextBox;
	ListView clientList;
	Button startButton;
	Button cancelButton;

	NetworkManager nm;

	ArrayAdapter<Player> adapter;

	Game currentGame;
	boolean host;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_host_game);

		ipTextBox  = (TextView) findViewById(R.id.ipTextBox);
		clientList = (ListView) findViewById(R.id.clientList);
		startButton = (Button) findViewById(R.id.startButton);
		cancelButton = (Button) findViewById(R.id.cancelButton);

		startButton.setOnClickListener(this);
		cancelButton.setOnClickListener(this);

		currentGame = Game.getInstance();
		currentGame.init();

		nm = NetworkManager.getInstance();
		nm.init(this);
		nm.setIncomingHandler(handler);

		startButton.setEnabled(false);

		adapter = new ArrayAdapter<Player>(this, android.R.layout.simple_list_item_1, currentGame.getPlayers());
		clientList.setAdapter(adapter);

		host = getIntent().getBooleanExtra("Host", false);		
		getUserName();
	}

	void joinServer(String ip, String playerJSON){
		int port = NetworkManager.SERVER_PORT; //Default port
		if(nm.connectToServer(ip, port)){
			nm.sendMessage("AddPlayer" + "&"+ playerJSON);//TODO:  parse out to constants
			startButton.setText("Waiting for host");
			ipTextBox.setText("Server: " + ip);
			adapter.notifyDataSetChanged();
		}
	}

	void startServer(){
		String ip = nm.startServer();
		ipTextBox.setText("Host: " + ip);
	}

	void syncPlayers(Player[] players){
		currentGame.playerList.clear();
		currentGame.playerList.addAll(Arrays.asList(players));
		adapter.notifyDataSetChanged();	
	}
	
	void addPlayerToHost(Player p){
		currentGame.getPlayers().add(p);
		adapter.notifyDataSetChanged();
		startButton.setEnabled(true);
	}

	void startGame(boolean hosting){
		Intent intent = new Intent(this, GameActivity.class);
		intent.putExtra("Host", hosting);
		startActivity(intent);
	}

	void showConnectDialog(Player clientPlayer){
		final Player player = clientPlayer;
		final EditText ipTextBox = new EditText(this);
		ipTextBox.setText(Preferences.getLastIP());
		ipTextBox.setFilters((new InputFilter[]{new InputFilter.LengthFilter(15)}));//15=Max ipv4 + dots
		ipTextBox.setInputType(InputType.TYPE_CLASS_PHONE);//closest to ip, numbers and periods
		ipTextBox.setSingleLine();
		AlertDialog mConnectDialog = new AlertDialog.Builder(this).create();
		mConnectDialog.setView(ipTextBox);
		mConnectDialog.setTitle("Connect to server");
		mConnectDialog.setMessage("Please enter an IP address");
		mConnectDialog.setButton(AlertDialog.BUTTON_POSITIVE,"Connect", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int whichButton) {
				String serverIP = ipTextBox.getText().toString().trim();
				Preferences.setLastIP(serverIP);//TODO:  verify its an ip				
				Message msg = Message.obtain();
				msg.arg1 = 1;
				msg.obj = serverIP + "&" + player.toJSON();
				handler.sendMessage(msg);
				dialog.dismiss();
			}
		});

		mConnectDialog.setButton(AlertDialog.BUTTON_NEGATIVE,"Cancel", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int whichButton) {
				//Cancel connection
				//stop server??
				Message msg = Message.obtain();
				msg.arg1 = -1;
				handler.sendMessage(msg);
				dialog.dismiss();
			}
		});

		mConnectDialog.show();
	}

	void getUserName(){
		final EditText nameTextBox = new EditText(this);
		nameTextBox.setText(Preferences.getLastName());

		AlertDialog getNameDialog = new AlertDialog.Builder(this).create();
		getNameDialog.setView(nameTextBox);
		getNameDialog.setTitle("Enter a name");
		getNameDialog.setMessage("Please enter a name");
		getNameDialog.setButton(AlertDialog.BUTTON_POSITIVE,"OK", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int whichButton) {
				String name = nameTextBox.getText().toString().trim();
				if(name !=null && !name.equals("")){
					Preferences.setLastName(name);
				}else{
					name = Preferences.LAST_NAME_DEFAULT;
				}
				Player p = new Player(name,nm.getLocalIpAddress(), host, false);


				Message msg = Message.obtain();
				msg.arg1 = 2;
				msg.obj = p;
				handler.sendMessage(msg);
			}
		});

		getNameDialog.setButton(AlertDialog.BUTTON_NEGATIVE,"Cancel", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int whichButton) {
				String name = Preferences.LAST_NAME_DEFAULT;
				Player p = new Player(name,nm.getLocalIpAddress(), host, false);
				Message msg = Message.obtain();
				msg.arg1 = 2;
				msg.obj = p;
				handler.sendMessage(msg);
			}
		});

		getNameDialog.show();
	}

	@Override
	public void onClick(View v) {
		switch(v.getId()){
		case R.id.startButton:
			startGame(true);
			nm.sendMessage("StartGame");
			break;
		case R.id.cancelButton:
			nm.stopServer();
			finish();
			break;
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.host_game, menu);
		return true;
	}

	public void exitHostingMenu(){
		finish();
	}
	
	public Handler handler = new Handler(new Handler.Callback() {
		@Override
		public boolean handleMessage(Message msg) {
			try{
				if(msg.arg1 == -1){//Cancel connection
					exitHostingMenu();
				}
				
				//Connect dialog
				if(msg.arg1 == 1){//Got ip from user
					String[] args = ((String)msg.obj).split("&");
					String ip = args[0];
					String playerJSON = args[1];
					joinServer(ip, playerJSON);
				}
				//Get Use Name dialog
				if(msg.arg1 == 2){//Get user Name
					if(host){
						//Add the host player
						currentGame.playerList.add((Player)msg.obj);
						adapter.notifyDataSetChanged();

						startServer();
					}else{
						Player clientPlayer = (Player)msg.obj;
						showConnectDialog(clientPlayer);
					}
				}


				//From NetworkManager
				if(msg.arg2 == 1){//A client has connected
					if(host){//I'm the host, so sync players with everyone else
						Player newPlayer = Player.fromJSON((String)msg.obj);
						addPlayerToHost(newPlayer);
						//Now send the new player list to all clients?? 
						nm.sendMessage("AddPlayer" + "&"+ currentGame.getPlayersAsJSON());//TODO:  parse out to constants
					}else{
						JSONArray ja = new JSONArray((String)msg.obj);
						Player[] players = new Player[ja.length()];
						for(int i = 0; i < ja.length(); i++){
							players[i] = Player.fromJSON(ja.get(i).toString());
						}
						syncPlayers(players);
					}
				}

				if(msg.arg2 == 2){//Message received
					String message = (String)msg.obj;
					Logger.popUp("[HostGame]: Received " + message);
					if(message.equals("StartGame")){
						startGame(false);
					}
				}
			}catch(Exception e){
				Logger.e(e);
			}
			return true;
		}
	});
}
